<?php

namespace app\api\controller;

use app\admin\model\Xcx;
use think\cache\driver\Redis;
use Pheanstalk\Pheanstalk;
use think\Db;
use think\Request;

// 发送模板消息
class Sendtmp extends Base
{

    public $redis;
    public $headers = array("Content-type: application/json;charset=UTF-8", "Accept: application/json", "Cache-Control: no-cache", "Pragma: no-cache");

    public function __construct(Request $request = null)
    {
        parent::__construct($request);
        $this->redis = new Redis();
    }

    // 获取小程序信息
    public function get_xcx()
    {
        $xcx = Xcx::get(10);
        return json($xcx);
    }

    // 调用微信api，获取access_token，有效期7200s
    public function get_access_token($appid)
    {
        // 在有效期，直接返回access_token
        if ($this->redis->has($appid)) {
            return $this->redis->get($appid);
        } else {
            // 不在有效期，重新发送请求，获取access_token
            $xcx = Xcx::where('appid', $appid)->find();

            $url = 'https://api.weixin.qq.com/cgi-bin/token';
            $params['grant_type'] = 'client_credential';
            $params['appid'] = $appid;
            $params['secret'] = $xcx->secret;

            $result = $this->http($url, $params);
            $res = json_decode($result, true);   //json字符串转数组

            if (array_key_exists('access_token', $res)) {
                $this->redis->set($appid, $res['access_token'], 7100);
                return $res['access_token'];
            } else {
                return false;
            }
        }
    }

    // 获取小程序下的模板消息信息
    public function get_tmp_list($appid)
    {
        $token = $this->get_access_token($appid);

        if ($token) {
            $url = 'https://api.weixin.qq.com/cgi-bin/wxopen/template/list?access_token=' . $token;
            $params = '{"offset": 0,"count": 10}';
            $res = $this->http($url, $params, $method = 'POST');
            $json = json_decode($res, true);
            if (array_key_exists('list', $json)) {
                return json($json['list']);
            }
        }
    }

    // 设置发送任务
    public function set_schedule()
    {
        $res = '';

        // 获取参数
        $appid = $this->request->post('appid');
        $send_type = $this->request->post('send_type');
        $test_openid = $this->request->post('test_openid');
        $tmp = json_decode($this->request->post('tmpMsg'), true);

        // 判断发送类型
        switch ($send_type) {
            case 'send_test':
                if ($test_openid != '') {
                    $res = $this->test_send($appid, $test_openid, $tmp);
                }
                break;
            case 'send_now':
                $res = $this->send_async($appid, $tmp);
                break;
        }
        if ($res) {
            return json('ok');
        } else {
            return json('error');
        }
    }

    // 测试发送
    public function test_send($appid, $test_openid, $tmp)
    {
        $res = '';
        $token = $this->get_access_token($appid);
        if ($token) {
            $res = $this->send_msg($token, $test_openid, $tmp);
        }
        return $res;
    }

    // 发送消息
    public function send_msg($token, $openid, $tmp)
    {
        $formId = $this->get_formid($openid); // 获取formId
        $url = 'https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=' . $token;
        $templateData = $this->create_template($openid, $tmp, $formId);//拼接模板数据
        $res = json_decode($this->http($url, $templateData, 'POST', $this->headers));
        if ($res->errcode == 0) {
            return true;
        } else {
            return false;
        }
    }

    // 拼装模板，创建通知内容
    private function create_template($openId, $tmp, $formId)
    {
        foreach ($tmp['data'] as $k => $v) {
            $templateData[$k]['value'] = $v['text'];
        }
        $data['emphasis_keyword'] = 'keyword1.DATA';
        $data['touser'] = $openId;
        $data['template_id'] = $tmp['template_id'];
        $data['page'] = $tmp['page'];
        $data['form_id'] = $formId;
        $data['data'] = $templateData;
        return json_encode($data);
    }

    // 取出一个可用的用户openId对应的推送码
    public function get_formid($openId)
    {
        $res = $this->_get($openId);
        if ($res) {
            if (!count($res)) {
                return FALSE;
            }
            $newData = array();
            $result = FALSE;
            for ($i = 0; $i < count($res); $i++) {
                if ($res[$i]['expire'] > time()) {
                    $result = $res[$i]['formId'];//得到一个可用的formId
                    for ($j = $i + 1; $j < count($res); $j++) {//移除本次使用的formId
                        array_push($newData, $res[$j]);//重新获取可用formId组成的新数组
                    }
                    break;
                }
            }
            $this->_save($openId, $newData);
            return $result;
        } else {
            return FALSE;
        }
    }

    // redis get
    private function _get($openid)
    {
        $data = $this->redis->get($openid);
        if ($data) return json_decode($data, TRUE);
        else return FALSE;
    }

    // redis set
    private function _save($openId, $data)
    {
        return $this->redis->set($openId, json_encode($data), 60 * 60 * 24 * 7);
    }

    // 写入
    public function write_all_openid($appid)
    {
        $txt = fopen('openids/' . $appid . '.txt', 'w') or die('Unable to open file!');
        $data = Db::table('fa_haibao_acc')->column('openid');
        foreach ($data as $openid) {
            if ($this->redis->has($openid)) {
                fwrite($txt, $openid . PHP_EOL);
            }
        }
        fclose($txt);
    }

    // 异步发送
    public function send_async($appid, $tmp)
    {
        $this->write_all_openid($appid);
        $pheastalk = new Pheanstalk('127.0.0.1');

        $data = array(
            'appid' => $appid,
            'tmp' => $tmp
        );

        if ($pheastalk->useTube('sendtmp')->put(json_encode($data), 2, 0, 60)) {
            return true;
        } else {
            return false;
        }
    }

}